using System;
using System.Web;
using System.Web.UI;
using CodeStory.Core.Attributes;
using System.ComponentModel;
using CodeStory.WebControls;

namespace CodeStory.Core.UI
{
	[ViewStateModeById()]
	public class Portlet : CodeStoryUserControl, IPortlet
	{
		private bool editMode;

		public bool EditMode {
			get { return editMode; }
			set { editMode = value; }
		}

		/// <summary>
		/// Get wether the portlet need to check user's permission.
		/// </summary>
		public virtual bool NeedAuthentication {
			get { return false; }
		}

		#region Settings
		private StateBag _setting;
		private PortletContainer portletContainer;

		protected StateBag Setting {
			get {
				if (_setting == null) {
					_setting = new StateBag();
					if (IsTrackingViewState) {
						((IStateManager)_setting).TrackViewState();
					}
				}
				return _setting;
			}
		}
		[PortletSetting]
		[Description("Wether to show the portlet in a container.")]
		public virtual bool ShowContainer {
			get {
				object obj = Setting["ShowContainer"];
				return obj == null ? true : (bool)obj;
			}
			set { Setting["ShowContainer"] = value; }
		}

		[PortletSetting]
		[Description("The Title of the portlet.")]
		public virtual string Title {
			get { 
				object obj = Setting["Title"];
				return obj == null ? string.Empty : (string)obj;
			}
			set { 
				Setting["Title"] = value;
				if (PortletContainer != null) {
					PortletContainer.PortletTitle = value;
				}
			}
		}

		[PortletSetting]
		[Description("Wether to show the portlet title.")]
		public virtual bool ShowTitle {
			get { 
				object obj = Setting["ShowTitle"];
				return obj == null ? true : (bool)obj;
			}
			set { Setting["ShowTitle"] = value; }
		}

		[PropertyEditor(typeof(ContainerEditor))]
		[PortletSetting]
		[Description("The container name of the portlet.")]
		public string ContainerName {
			get {
				object obj = Setting["ContainerName"];
				return obj == null ? CodeStorySiteSetting.Current.DefaultContainerName : (string)obj;
			}
			set { Setting["ContainerName"] = value; }
		}
		public PortletContainer PortletContainer {
			get { return portletContainer; }
			set { portletContainer = value; }
		}
		#endregion

		#region Override properties
		public override bool Visible {
			get {
				if (PortletContainer != null) {
					return PortletContainer.Visible && base.Visible;
				}
				return base.Visible;
			}
			set {
				if (PortletContainer != null) {
					PortletContainer.Visible = value;
				}
				base.Visible = value;
			}
		} 
		#endregion

		#region Message
		/// <summary>
		/// 
		/// </summary>
		/// <param name="commandID"></param>
		/// <param name="msg"></param>
		/// <returns></returns>
		protected int SendMessage(string commandID, object msg) {
			ILayoutPage page = this.Page as ILayoutPage;
			if (page == null) {
				page = HttpContext.Current.Handler as ILayoutPage;
			}
			if (page == null) {
				return -1;
			}
			int count = 0;
			foreach (Control uc in page.UserControlsInPage) {
				if (object.ReferenceEquals(this, uc)) {
					continue;
				}
				Portlet p = uc as Portlet;
				if (p == null) {
					continue;
				}
				bool hasHandled = p.ProcessMessage(this, commandID, msg);
				if (hasHandled) {
					count++;
				}
			}
			return count;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="commandID"></param>
		/// <param name="msg"></param>
		/// <returns></returns>
		protected virtual bool ProcessMessage(object sender, string commandID, object msg) {
			return false;
		}
		#endregion

		#region Navigation

		protected void Navigate(Type type) {
			Navigate(type, null);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="type"></param>
		/// <param name="querystring"></param>
		protected void Navigate(Type type, params string[] querystring) {
			ILayoutPage page = this.Page as LayoutPage;
			if (page == null) {
				page = HttpContext.Current.Handler as ILayoutPage;
			}
			if (page == null) {
				return;
			}
			foreach (Control c in page.UserControlsInPage) {
				Type t = c.GetType();
				if (t.IsSubclassOf(type) || t.Equals(type)) {
					bool flag = CheckQuery(querystring);
					if (flag) {
						return;
					} else {
						break;
					}
				}
			}

			NavigationPortletAttribute attr = Attribute.GetCustomAttribute(type, typeof(NavigationPortletAttribute)) as NavigationPortletAttribute;
			if (attr == null) {
				return;
			}
			string query = string.Empty;
			if (querystring != null) {
				query = string.Join("&", querystring);
			}
			if (query.Length > 0) {
				query = "?" + query;
			}

			Response.Redirect(string.Format("~/{0}.portlet.aspx{1}", attr.NavigationName, query));
		}

		private bool CheckQuery(string[] querystring) {
			bool flag = true;
			if (querystring != null) {
				foreach (string str in querystring) {
					string[] pa = str.Split('=');
					if (pa.Length == 2) {
						string s = Request.QueryString[pa[0]];
						if (!string.Equals(s, pa[1], StringComparison.OrdinalIgnoreCase)) {
							flag = false;
							break;
						}
					} else {
					}
				}
			}
			return flag;
		}
		#endregion

		#region IPortlet Members
		public void LoadSetting(object setting) {
			if (setting != null) {
				((IStateManager)Setting).LoadViewState(setting);
			}
		}

		public object SaveSetting() {
			if (_setting != null) {
				return ((IStateManager)_setting).SaveViewState();
			}
			return null;
		}

		public void TrackSetting() {
			((IStateManager)Setting).TrackViewState();
		}

		void IPortlet.LoadSetting(object setting) {
			this.LoadSetting(setting);
		}

		object IPortlet.SaveSetting() {
			return this.SaveSetting();
		}

		void IPortlet.TrackSetting() {
			this.TrackSetting();
		}
		#endregion
	}
}